Computer Graphics
|
Lecture
10 |
Surfaces
in real world environments receive light in 3 ways:
1.
Directly from existing light sources such as the sun or a
lit candle
2.
Light that passes and refracts through transparent objects
such as water or a glass vase
3.
Light reflected, bounced, or diffused from other exisiting
surfaces in the environment
· Material
Models
Lambert's
cosine law of reflection as shown in the above diagram:
1. n; a normal vector to the surface to be illuminated.
2. L, a vector from the surface
position that points towards the light source.
3. Il, an
intensity for a point light source.
4. kd ,
a diffuse reflection constant.
Equation
gives the brightness of a surface point in terms of the brightness of a light
source and its orientation relative to the surface normal vector, n,
·
I is the reflected
intensity
Measures how bright the surface is
at that point.
· Surface
brightness varies as a function of the angle between n and L
When n and L coincide, the
light source is directly overhead.
· I is at a
maximum and cosq = 1.
As the angle increases to 90o,
the cosine decreases the intensity to 0.
· All the
quantities in the equation are normalized between 0 and 1.
· I is
converted into frame buffer intensity values by multiplying by the number of
shades available.
· With 28
= 256 possible shades, we have 1 * 255, the brightest frame buffer intensity.
· For n and L at an angle of 45 o, I = cos 45 o * 256 =
181.
·
Simple illuminated model is unable to directly accommodate
all scattered light
·
It is grouped together as independent intensity, Ia.
·
The formula becomes
·
Iaka is the ambient illumination term,
taking into account the additional environmental illumination, Ia, and the
ability of the object to absorb it, ka.
·
Below Figure: Only ambient illumination
·
d is the distance from the light source to the object
·
Regions of significant brightness, exhibited as spots or bands,
characterize objects that specularly reflect light.
·
Specular highlights originate from smooth, sometimes
mirrorlike surfaces
·
Fresnel equation is used to simulate this effect.
·
The Fresnel equation states that for a perfectly reflecting
surface the angle of incidence equals the angle of reflection.
·
Most objects are not perfect mirrors.
o
some angular scattering of light.
o
If the viewer increases the angle (a ) between
himself, the line of sight vector (S),
and the reflectance vector (R), the
bright spot gradually disappears.
o
Smooth surfaces scatter light less then rough surfaces.
o
This produces more localized highlights.
o
Building this effect into the lighting model gives
·
Specular reflectance term possesses a specular reflectance
constant, ks.
·
The cosine term is raised to the nth power.
o
Small values of n (e.g. 5) distribute the specular
highlights, characteristic of glossy paper.
o
High values of n (e.g. 50) are characteristic of metals.
1. Simple
Illumination Model
Use the
following formula for diffuse + ambient illumination
0
£ q £ p/2
1. Determine
polygon’s surface normal
2. Calculate cosine
of angle between surface normal and illumination vector
3. Scale to
frame buffer values between 0 and 255
1. Determine
polygon’s surface normal
i. Begin with
polygon vertices
|
x |
y |
z |
1 |
0.750 |
0.250 |
0.000 |
2 |
0.250 |
0.750 |
0.000 |
3 |
0.125 |
0.750 |
0.217 |
4 |
0.375 |
0.250 |
0.650 |
ii. Create
vectors P and Q
P = [ P2 –
P1] = [ Px Py Pz ] = [ x2 – x1 y2 –
y1 z2 – z1 ]
= [ -0.500 0.500 0.000
]
Q = [ P3 –
P2] = [ Qx Qy Qz ] = [ x2 – x2 y3 –
y2 z3 – z2 ]
= [ -0.125 0.000 0.217 ]
iii. Determine
length of P and Q
|P| = sqrt( Px2 + Py2 + Pz2 ) =
0.7071
|Q| = sqrt( Qx2 + Qy2 + Qz2 ) =
0.2500
iv. Normalize P
and Q
P(norm) = P
/ |P| = [ Px / |P| Py / |P|
Pz / |P| ]
= [ -0.7071 0.7071 0.0000 ]
Q(norm) = Q
/ |Q| = [ Qx / |Q| Qy /
|Q| Qz / |Q| ]
= [ -0.5000 0.0000 0.8660 ]
v. Calculate
normal vector using cross product:
n = PxQ |
|
nx = PyQz - PzQy |
|
ny = PzQx -PxQz |
|
nz = PxQy - PyQx |
n = [nx nx nx] = [0.1083 0.1083 0.0625]
vi. Normalize n
|n| = |
0.165359 |
|
||||
|
n(Norm) = |
[0.6547 |
0.6547 |
0.3780 ] |
||
vii. Create a
light vector
· Select a
point on the polygon surface and position for the light source
o A polygon
vertex may be selected or a position inside the polygon.
o Here we select
a position inside the polygon by calculating the midpoint between the 1st
and 3rd vertices
(xmid, ymid, zmid) = ( (x1 + x3)/2 , (y1 + y3)/2 , (z1 + z3)/2 )
= (0.438 |
0.500 |
0.108) |
o A position
for the light source is give as
x |
y |
z |
10 |
10 |
-5 |
Note: If observer is in –z direction than z value of light is also –z.
· Compute
light vector L
|
|
Lx |
Ly |
Lz |
|
Light
Vector (L) |
9.563 |
9.500 |
-5.108 |
|
|L| |
14.415 |
|
|
|
L(Norm) |
0.66338 |
0.65905 |
-0.35438 |
2. Calculate
cosine of angle between surface normal and illumination vector
i. Use dot
product formula:
nlL =
(nxLx+nyLy+nzLz)=|n||L|cosq |
Since n and L are
already normalized the formula reduces to
nlL =
(nxLx+nyLy+nzLz) = cosq |
||
|
= 0.7318 |
|
3. Scale to
frame buffer values between 0 and 255
0.7318 * 255 = int(186.6) = 186
Shades each polygon of an object based on the angle between
the polygon's surface normal and the direction of the light source.
Disadvantage - it gives low-polygon models a
faceted look. Sometimes this look can be advantageous though, such as in
modeling boxy objects. Artists sometimes use flat shading to look at the
polygons of a solid model they are creating.
Gouraud shading (Henri Gouraud, 1971) is used to achieve
smooth lighting on low-polygon surfaces using the Lambertian diffuse lighting
model.
1. Calculates the surface normals for the polygons.
2. Normals are then averaged for all the polygons that
meet at each vertex to produce a vertex normal.
3. Lighting computations are then performed to produce
intensities at vertices.
4. These intensities are interpolated along the
edges of the polygons.
5. The polygon is filled by lines drawn across it that
interpolate between the previously calculated edge intensities.
Advantage - Gouraud shading is superior to
flat shading which requires significantly less processing than Gouraud, but
gives low-polygon models a sharp, faceted look.
·
An improved version of
Gouraud shading that provides a better approximation to the Phong shading
model.
·
Main problem with
Gouraud shading - when a specular highlight occurs near the center of a large triangle,
it will usually be missed entirely. Phong shading fixes the problem.
1. Calculate the surface normals at the vertices of
polygons in a 3D computer model.
2. Normals are then averaged for all the polygons that
meet at each vertex.
3. These normals are interpolated along the edges
of the polygons.
4. Lighting computations are then performed to produce
intensities at positions along scanlines.
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_LIGHT0);
float [] lightColor = {1.0f, 1.0f, 1.0f,
1.0f};
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE,
lightColor);
float [] lightPosition = {5, 5, 5, 1};
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION,
lightPosition);
gl.glEnable(GL.GL_COLOR_MATERIAL);
gl.glColorMaterial(GL.GL_FRONT_AND_BACK,
GL.GL_DIFFUSE);
import
java.awt.*;
import
java.awt.event.*;
import
net.java.games.jogl.*;
public class
CubeLight
{
static Animator animator = null;
static class Renderer
implements GLEventListener,
KeyListener
{
private float rquad = 0.0f;
public void display(GLDrawable gLDrawable)
{
final GL gl = gLDrawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT |
GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -15.0f);
gl.glRotatef(rquad, 0.5f, 1.0f, 0.5f);
gl.glBegin(GL.GL_QUADS); //
Draw A Quad
gl.glColor3f(0.0f,1.0f,0.0f);
gl.glNormal3f(0.0f,
1.0f, 0.0f);
gl.glVertex3f(
1.0f, 1.0f,-1.0f);
gl.glVertex3f(-1.0f,
1.0f,-1.0f);
gl.glVertex3f(-1.0f,
1.0f, 1.0f);
gl.glVertex3f(
1.0f, 1.0f, 1.0f);
gl.glColor3f(1.0f,0.5f,0.0f);
gl.glNormal3f(0.0f,
-1.0f, 0.0f);
gl.glVertex3f(
1.0f,-1.0f, 1.0f);
gl.glVertex3f(-1.0f,-1.0f,
1.0f);
gl.glVertex3f(-1.0f,-1.0f,-1.0f);
gl.glVertex3f(
1.0f,-1.0f,-1.0f);
gl.glColor3f(1.0f,0.0f,0.0f);
gl.glNormal3f(0.0f,
0.0f, 1.0f);
gl.glVertex3f(
1.0f, 1.0f, 1.0f);
gl.glVertex3f(-1.0f,
1.0f, 1.0f);
gl.glVertex3f(-1.0f,-1.0f,
1.0f);
gl.glVertex3f(
1.0f,-1.0f, 1.0f);
gl.glColor3f(1.0f,1.0f,0.0f);
gl.glNormal3f(0.0f,
0.0f, -1.0f);
gl.glVertex3f(
1.0f,-1.0f,-1.0f);
gl.glVertex3f(-1.0f,-1.0f,-1.0f);
gl.glVertex3f(-1.0f,
1.0f,-1.0f);
gl.glVertex3f(
1.0f, 1.0f,-1.0f);
gl.glColor3f(0.0f,0.0f,1.0f);
gl.glNormal3f(-1.0f,
0.0f, 0.0f);
gl.glVertex3f(-1.0f,
1.0f, 1.0f);
gl.glVertex3f(-1.0f,
1.0f,-1.0f);
gl.glVertex3f(-1.0f,-1.0f,-1.0f);
gl.glVertex3f(-1.0f,-1.0f,
1.0f);
gl.glColor3f(0.5f,0.5f,0.5f);
gl.glNormal3f(1.0f,
0.0f, 0.0f);
gl.glVertex3f(
1.0f, 1.0f,-1.0f);
gl.glVertex3f(
1.0f, 1.0f, 1.0f);
gl.glVertex3f(
1.0f,-1.0f, 1.0f);
gl.glVertex3f(
1.0f,-1.0f,-1.0f);
gl.glEnd();
gl.glFlush();
rquad += 0.15f;
}
public
void displayChanged(GLDrawable gLDrawable, boolean modeChanged, boolean
deviceChanged)
{
}
public void init(GLDrawable gLDrawable)
{
final GL gl = gLDrawable.getGL();
final GLU glu = gLDrawable.getGLU();
gl.glShadeModel(GL.GL_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f,
0.5f); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, 0.0f);
glu.gluPerspective(20.0f, 1.0, 6.0,
20.0);
float [] lightPosition = {5, 5, 5, 1};
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION,
lightPosition);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_LIGHT0);
float
[] lightColor = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glLightfv(GL.GL_LIGHT0,
GL.GL_DIFFUSE, lightColor);
gl.glEnable(GL.GL_COLOR_MATERIAL);
gl.glColorMaterial(GL.GL_FRONT_AND_BACK,
GL.GL_DIFFUSE);
gLDrawable.addKeyListener(this);
}
public void reshape(GLDrawable gLDrawable, int x, int y, int
width, int height)
{
}
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() ==
KeyEvent.VK_ESCAPE)
{
animator.stop();
System.exit(0);
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
public static void main(String[] args)
{
Frame frame = new Frame("Lesson 5: 3D
Shapes");
GLCanvas canvas =
GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
canvas.addGLEventListener(new Renderer());
frame.add(canvas);
frame.setSize(500, 500);
animator = new Animator(canvas);
frame.addWindowListener(new
WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
animator.stop();
System.exit(0);
}
});
frame.show();
animator.start();
canvas.requestFocus();
}
}